﻿#include <iostream>
#include <Windows.h>
#include "MainWidget.h"
#include "serial_example.h"
#include "UartWriteFile.h"
#include "MyQueue.h"
#include "serial/serial.h"


using namespace std;

HANDLE Handle_uart_rev = NULL;
HANDLE Handle_uart_send = NULL;

Queue MyQueue;
UartWriteFile SaveDataObj;			//Save file obj.
serial::Serial* my_serial = NULL;

typedef struct __uart_rev_flag_t
{
	bool uart_open_rev;
	bool close_switch;
	bool close_status;
	
}uart_rev_flag_t;

typedef struct __uart_send_flag_t
{
	bool uart_open_send;
	bool close_switch;
	bool close_status;
	
}uart_send_flag_t;

struct __uart_close_falg_t
{
	uart_rev_flag_t rev_flag;
	uart_send_flag_t send_flag;

}uart_close_falg_t = {false, false, false, false, false, false};


DWORD WINAPI uart_run_receive(LPVOID lpThreadParameter)
{
	serial::Serial* my_serial = (serial::Serial*)lpThreadParameter;

	uart_close_falg_t.rev_flag.uart_open_rev = true; //True open suceess. flase not open.
	
	while (1)
	{
		run(*my_serial, SaveDataObj);

		if (uart_close_falg_t.rev_flag.close_switch)
		{
			/* Exit. */
			break;
		}
	}

	uart_close_falg_t.rev_flag.close_status = true;

	return 0;
}


DWORD WINAPI uart_run_send(LPVOID lpThreadParameter)
{
	serial::Serial* my_serial = (serial::Serial*)lpThreadParameter;

	char ReceiveData[DATA_MAX_SIZE];
	size_t DataLength = 0;

	uart_close_falg_t.send_flag.uart_open_send = true;
	
	while(1)
	{
		if(true != MyQueue.IsEmpty())
		{
			memset(ReceiveData, 0, DATA_MAX_SIZE);
			
			DataLength = MyQueue.Dequeue(ReceiveData, DATA_MAX_SIZE);

			if(DataLength != 0)
			{
				ReceiveData[DataLength] = '\r\n';
				run_send(*my_serial, (const uint8_t*)ReceiveData, DataLength+1);
			}
		}

		if (uart_close_falg_t.send_flag.close_switch)
		{
			/* exit. */
			break;
		}
	}

	uart_close_falg_t.send_flag.close_status = true;

	return 0;
}


bool CreateUarteReceiveTask(void* p)
{
	bool CreateStatus = true;
	
	if(Handle_uart_rev == NULL)
	{
		Handle_uart_rev = CreateThread(NULL, 0, uart_run_receive, p, CREATE_SUSPENDED, NULL);
		if (Handle_uart_rev == NULL)
		{
			cout << "Open uart fail  ！！！." << endl;
			CreateStatus = false;
		}
		
		/* Wake up thread.*/
		ResumeThread(Handle_uart_rev);
	}
	else
	{
		/* Wake up thread.*/
		ResumeThread(Handle_uart_rev);
	}

	return CreateStatus;
}


bool CreateUarteSendTask(void* p)
{
	bool CreateStatus = true;
	
	if(Handle_uart_send == NULL)
	{
		Handle_uart_send = CreateThread(NULL, 0, uart_run_send, p, CREATE_SUSPENDED, NULL);
		if (Handle_uart_send == NULL)
		{
			cout << "Open uart fail  ！！！." << endl;
			CreateStatus = false;
		}
		
		/* Wake up thread.*/
		ResumeThread(Handle_uart_send);
	}
	else
	{
		/* Wake up thread.*/
		ResumeThread(Handle_uart_send);
	}

	return CreateStatus;
}

serial::Serial* OpenUart(uart_infor_t* p)
{
	uart_infor_t* u_infor = p;

	cout << "Start uart:" << u_infor->uart_port << endl;
	cout << "baudt:" << u_infor->uart_baud << endl;


	string port(u_infor->uart_port);

	static serial::Serial my_serial(port, atoi(u_infor->uart_baud));

	cout << "Is the serial port open?";
	if (my_serial.isOpen())
	{
		/* Set read write timeout time. */
		my_serial.setTimeout(serial::Timeout::max(), 250, 0, 250, 0);
		
		cout << " Yes." << endl;
	}
	else
		cout << " No." << endl;

	return &my_serial;
}

void StartUart(Fl_Widget* w, void* p)
{	
	Fl_Button* StartButton = (Fl_Button*)w;
	
	static serial::Serial open_serial;

	if(my_serial != NULL)
	{
		CloseUart( w, p);
		StartButton->label("START");
		my_serial = NULL;
		memset(&uart_close_falg_t, 0, sizeof(uart_close_falg_t));
		Handle_uart_rev = NULL;
		Handle_uart_send = NULL;
		return ;
	}
	
	uart_infor_t* s_uart_infor = (uart_infor_t*)p;

	if(strlen(s_uart_infor->uart_baud) == 0 || strlen(s_uart_infor->uart_port) == 0)
	{
		cout << "Dear^_^! Please input port and baud information. OK?" << endl;
		
		return ;
	}
	
	my_serial = OpenUart((uart_infor_t*)p);
	
	
	if( CreateUarteSendTask((void*)my_serial))
	{
		if(true != CreateUarteReceiveTask((void*)my_serial))
		{
			cout << "Open receive fail" << endl;
			CloseHandle(Handle_uart_rev);
			return ;
		}
		StartButton->label("STOP");
		
	}
	else
	{
		cout << "Open send fail" << endl;
		CloseHandle(Handle_uart_rev);
	}
}

/* Stop uart */
void StopUart(Fl_Widget* w, void* p)
{
	DWORD start_falg = 0xfffff;
	
	/* Stop thread.*/
	start_falg = SuspendThread(Handle_uart_rev); 
	start_falg = SuspendThread(Handle_uart_send); 
	
}

bool set_rev_close_uart_flag(void)
{
	uart_close_falg_t.rev_flag.close_switch = true;

	Sleep(200);

	if(uart_close_falg_t.rev_flag.close_status)
	{
		/* Receive taks close success.*/
		return true;
	}

	return false;
}


bool set_send_close_uart_flag(void)
{
	uart_close_falg_t.send_flag.close_switch = true;

	Sleep(200);

	if(uart_close_falg_t.send_flag.close_status)
	{
		/* Send taks close success.*/
		return true;
	}

	return false;
}


/* Exit */
void CloseUart(Fl_Widget* w, void* p)
{
	if(uart_close_falg_t.send_flag.uart_open_send)
	{
		while (!set_send_close_uart_flag());

		CloseHandle(Handle_uart_send);
	}
	
	if(uart_close_falg_t.rev_flag.uart_open_rev)
	{
		while (!set_rev_close_uart_flag());

		CloseHandle(Handle_uart_rev );
	}
	
	//exit(0);
}


void SaveFileCbk(Fl_Widget* w, void* p)
{
	Fl_Button* b = (Fl_Button*)w->parent()->child(7);

	SaveDataObj.WriteToOpenFile((char*)p);

	b->activate();
}

void CloseFileCbk(Fl_Widget* w, void* p)
{
	MainWidget* b = (MainWidget*)w;
	
	SaveDataObj.WriteCloseFile();
}

void SendDataCbk(Fl_Widget* w, void* p)
{
	Fl_Button* b = (Fl_Button*)w;
	
	Fl_Input* iw = (Fl_Input*)b->parent()->child(2);
	
	MyQueue.Enqueue(iw->value(), iw->size());

	
}

/*Get uart information button callback.*/
static void get_uart_infor_cbk(Fl_Widget* w, void* p)
{
	Fl_Button* b = (Fl_Button*)w;
	find_port_infor();
}

void MainWidget::get_uart_information(void)
{
	PortInfo->callback(get_uart_infor_cbk, NULL);
}

/*Get uart information button callback.*/
static void get_uart_port_cbk(Fl_Widget* w, void* p)
{
	Fl_Button* b = (Fl_Button*)w;
	Fl_Input* iw = (Fl_Input*)b->parent()->child(0);

	iw->value();
	memcpy(p, iw->value(), iw->size());
}

void MainWidget::get_uart_port(char* uart_port)
{
	if (uart_port == NULL)
	{
		cout << "port buffer is empty" << endl;
	}
	memset(uart_port, 0, UART_PROT_SIZE);
	Prot->callback(get_uart_port_cbk, (void*)uart_port);

}


/*Get uart information button callback.*/
static void get_uart_baud_cbk(Fl_Widget* w, void* p)
{
	Fl_Button* b = (Fl_Button*)w;
	Fl_Input* iw = (Fl_Input*)b->parent()->child(1);

	iw->value();

	memcpy(p, iw->value(), iw->size());
}

void MainWidget::get_uart_baud(char* uart_baud)
{
	if (uart_baud == NULL)
	{
		cout << "uart_baud buffer is empty" << endl;
	}
	memset(uart_baud, 0, UART_BAUD_SIZE);

	Baud->callback(get_uart_baud_cbk, (void*)uart_baud);
}

